package com.thx.org.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;

import com.thx.common.spring.BeanFactory;
import com.thx.org.Org;
import com.thx.org.OrgChangeListener;
import com.thx.org.OrgManager;
import com.thx.org.model.Department;

/**
 * @author balance
 *
 */
public class OrgManagerImpl implements OrgManager {

  private DepartmentManager depMgr;

  private CompanyManager comMgr;

  private static HashMap<Class, OrgChangeListener> listeners;

  private static OrgManager orgMgr;

  public final int EVENT_SAVE = 1;
  public final int EVENT_UPDATE = 2;
  public final int EVENT_DELETE = 3;

  private OrgManagerImpl() {

  }

  private void init() {
    if (depMgr == null) {
      depMgr = (DepartmentManager) BeanFactory.getBean(DepartmentManager.class);
      depMgr.setOrgMgr(this);
    }

    if (comMgr == null) {
      comMgr = (CompanyManager) BeanFactory.getBean(CompanyManager.class);
      comMgr.setOrgMgr(this);
    }
  }

  public static OrgManager getInstance() {
    if (orgMgr == null) {
      synchronized (OrgManagerImpl.class) {

        if (orgMgr == null)
          orgMgr = new OrgManagerImpl();
      }
    }
    return orgMgr;
  }

  @Override
  public List<? extends Org> getChildren(String orgId) {
    init();
    return getChildrenRecursive(orgId);
  }

  private List<Department> getChildrenRecursive(String orgId) {
    List<Department> children = depMgr.getByParentId(orgId);
    if (children != null && children.size() > 0) {
      for (Department dep : children) {
        dep.setChildren(getChildrenRecursive(dep.getDepId()));
      }
    }
    return children;
  }

  public Org getRoot() {
    // TODO Auto-generated method stub
    init();
    return null;
  }

  @Override
  public void addListener(OrgChangeListener listener) {
    if (listener == null)
      return;
    synchronized (this) {
      if (listeners == null)
        listeners = new HashMap<Class, OrgChangeListener>();

      if (!listeners.containsKey(listener.getClass()))
        listeners.put(listener.getClass(), listener);
    }
  }

  @Override
  public void removeListener(OrgChangeListener listener) {
    if (listener == null || listeners == null)
      return;
    synchronized (this) {
      listeners.remove(listener.getClass());
    }
  }

  public boolean notify(int EvenType, Org org) {

    boolean ok = true;

    if (listeners != null && listeners.size() > 0) {
      Set<Entry<Class, OrgChangeListener>> set = listeners.entrySet();

      switch (EvenType) {
        case EVENT_SAVE:
          for (Entry<Class, OrgChangeListener> entry : set) {
            OrgChangeListener listener = entry.getValue();
            ok = ok && listener.onAdd(org);
          }
          break;
        case EVENT_UPDATE:
          for (Entry<Class, OrgChangeListener> entry : set) {
            OrgChangeListener listener = entry.getValue();
            ok = ok && listener.onUpdate(org);
          }
          break;
        case EVENT_DELETE:
          for (Entry<Class, OrgChangeListener> entry : set) {
            OrgChangeListener listener = entry.getValue();
            ok = ok && listener.onDelete(org);
          }
      }
    }

    return ok;
  }
}
